<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ios 3D引擎 SceneKit 开发(1) --起始篇</title>
<link rel="stylesheet" href="https://stackedit.io/res-min/themes/base.css" />
<script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML"></script>
</head>
<body><div class="container"><p>hello ,大家好，我是Roc.Tian，最近一直在研究苹果自家的3D&nbsp;引擎 SceneKit ,适当写写博客，总结一下，与大家分享一下，也希望跟大家交流，共同进步。 <br>
</p>

<p>
    <br>

</p>

<p>
    SceneKit 是一个OC 框架，开始之前，先熟悉一下SceneKit 的三维坐标系：<br>

</p>

<p>
    <img src="http://img.blog.csdn.net/20151215130133143?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt=""><br>

</p>

<p>
    在开始开发之前，一定要了解下面这几个非常重要的类
</p>

<p>
    </p><table cellspacing="0" cellpadding="0" class="t1    ">
        <tbody>
            <tr>
                <td valign="baseline" class="td1">
                    <p class="p1">
                        <span class="s1">类 / 协议</span>
                    </p>
                </td>
                <td valign="baseline" class="td2">
                    <p class="p1">
                        描述
                    </p>
                </td>
            </tr>
            <tr>
                <td valign="middle" class="td3">
                    <p class="p2">
                        <span class="s1"><a target="_blank" href="file:///Users/tianpengfei/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.iOS.docset/Contents/Resources/Documents/documentation/SceneKit/Reference/SCNView_Class/index.html#//apple_ref/occ/cl/SCNView">SCNView</a></span><span class="s2"> &amp; <a target="_blank" href="file:///Users/tianpengfei/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.iOS.docset/Contents/Resources/Documents/documentation/SceneKit/Reference/SCNSceneRenderer_Protocol/index.html#//apple_ref/occ/intf/SCNSceneRenderer"><span class="s3">SCNSceneRenderer</span></a></span>
                    </p>
                </td>
                <td valign="middle" class="td4">
                    <p class="p1">
                        &nbsp; 类似UIView，用来显示&nbsp;SceneKit 的内容，定义了一些代理方法，可以用 addSubView 方法添加到UiView 中
                    </p>
                </td>
            </tr>
            <tr>
                <td valign="middle" class="td3">
                    <p class="p2">
                        <br>

                    </p>
                    <p class="p2">
                        <br>

                    </p>
                    <p class="p2">
                        <span class="s1"><a target="_blank" href="file:///Users/tianpengfei/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.iOS.docset/Contents/Resources/Documents/documentation/SceneKit/Reference/SCNScene_Class/index.html#//apple_ref/occ/cl/SCNScene">SCNScene<span class="s3"></span></a></span>
                    </p>
                </td>
                <td valign="middle" class="td4">
                    <p class="p1">
                        <span class="s1"><br>
                        </span>
                    </p>
                    <p class="p1">
                        SceneKit 内容的容器. 你可以从3D建模工具生成的.dae文件中加载一个场景，或者用代码创建一个 ，然后把它显示在视图上
                    </p>
                </td>
            </tr>
            <tr>
                <td valign="middle" class="td3">
                    <p class="p2">
                        <br>

                    </p>
                    <p class="p2">
                        <br>

                    </p>
                    <p class="p2">
                        <span class="s1"><a target="_blank" href="file:///Users/tianpengfei/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.iOS.docset/Contents/Resources/Documents/documentation/SceneKit/Reference/SCNNode_Class/index.html#//apple_ref/occ/cl/SCNNode">SCNNode<span class="s3"></span></a></span>
                    </p>
                </td>
                <td valign="middle" class="td4">
                    <p class="p1">
                        <span class="s1"><br>
                        </span>
                    </p>
                    <p class="p1">
                        <span class="s1"><br>
                        </span>
                    </p>
                    <p class="p1">
                        <span class="s1">一个场景的基本构建块，你可以把摄像机，灯光，几何体附加到节点上</span>
                    </p>
                </td>
            </tr>
            <tr>
                <td valign="middle" class="td3">
                    <p class="p2">
                        <br>

                    </p>
                    <p class="p2">
                        <span class="s1"><a target="_blank" href="file:///Users/tianpengfei/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.iOS.docset/Contents/Resources/Documents/documentation/SceneKit/Reference/SCNGeometry_Class/index.html#//apple_ref/occ/cl/SCNGeometry">SCNGeometry<span class="s3"></span></a></span>
                    </p>
                </td>
                <td valign="middle" class="td4">
                    <p class="p1">
                        <span class="s1"></span>
                    </p>
                    <br>
                    <br>
                    一个可以连接到一个节点的三维物体。一个几何体（有时称为模型或网格）只定义了一个可见物体的形状。要定义对象的表面颜色图案，你必需要给几何体要附加材料。然后给材料贴图，或者上色，这个几何体表面才会有颜色，或者图案。<br>
                    <br>
                    你可以从3D建模工具生成的.dae文件中加载一个几何体，也可以用代码创建，SceneKit 提供了几种常见几何体，是<a target="_blank" href="file:///Users/tianpengfei/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.iOS.docset/Contents/Resources/Documents/documentation/SceneKit/Reference/SCNGeometry_Class/index.html#//apple_ref/occ/cl/SCNGeometry">SCNGeometry</a>&nbsp;的子类，比如长方体，球，圆柱球等等，后面我们会写一个demo会把官方提供的几何体给大家列出来，给大家一个直观的感受。 当然我们也可以用三维坐标，法向量自定义几何体，也可以讲一个2D 图案转化成一个具有深度(厚度)的三维几何体。后面应该专门有一篇会讲到利用贝塞尔曲线将一个2D 图案转化成一个具有深度(厚度)的三维几何体。<br>

                    <p class="p1">
                        <span class="s1"></span>
                    </p>
                </td>
            </tr>
            <tr>
                <td valign="middle" class="td3">
                    <p class="p2">
                        <br>

                    </p>
                    <p class="p2">
                        <br>

                    </p>
                    <p class="p2">
                        <span class="s1"><a target="_blank" href="file:///Users/tianpengfei/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.iOS.docset/Contents/Resources/Documents/documentation/SceneKit/Reference/SCNMaterial_Class/index.html#//apple_ref/occ/cl/SCNMaterial">SCNMaterial<span class="s3"></span></a></span>
                    </p>
                </td>
                <td valign="middle" class="td4">
                    <p class="p1">
                        <br>

                    </p>
                    <p class="p1">
                        <br>

                    </p>
                    <p class="p1">
                        材质，由于在3D建模工具中呈现球形，所以也叫材质球。上色，贴图全靠它。
                    </p>
                </td>
            </tr>
            <tr>
                <td valign="middle" class="td3">
                    <p class="p2">
                        <br>

                    </p>
                    <p class="p2">
                        <span class="s1"><a target="_blank" href="file:///Users/tianpengfei/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.iOS.docset/Contents/Resources/Documents/documentation/SceneKit/Reference/SCNLight_Class/index.html#//apple_ref/occ/cl/SCNLight">SCNLight<span class="s3"></span></a></span>
                    </p>
                </td>
                <td valign="middle" class="td4">
                    <p class="p1">
                        <br>

                    </p>
                    <p class="p1">
                        光源可以附加到节点上，在渲染场景中提供着色<br>

                    </p>
                </td>
            </tr>
            <tr>
                <td valign="middle" class="td3">
                    <p class="p2">
                        <br>

                    </p>
                    <p class="p2">
                        <span class="s1"><a target="_blank" href="file:///Users/tianpengfei/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.iOS.docset/Contents/Resources/Documents/documentation/SceneKit/Reference/SCNCamera_Class/index.html#//apple_ref/occ/cl/SCNCamera">SCNCamera<span class="s3"></span></a></span>
                    </p>
                </td>
                <td valign="middle" class="td4">
                    <p class="p1">
                        <br>

                    </p>
                    <p class="p1">
                        虚拟摄像机可以附加到节点上，提供了一个场景的视图。<br>

                    </p>
                </td>
            </tr>
        </tbody>
    </table>
    <br>

<p></p>

<p>
    <br>

</p>

<p>
    了解以上知识，那我们就来动手开发吧，我们可以在Xcode &nbsp; 中新建一个SceneKit 项目：
</p>

<p>
    <br>

</p>

<p>
    <img src="http://img.blog.csdn.net/20151215134334877?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt=""><br>

</p>

<p>
    <br>

</p>

<p>
    运行效果如下：
</p>

<p>
    <img src="http://img.blog.csdn.net/20151215144409371?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt=""><br>

</p>

<p>
    <br>

</p>

<p>
    这个新建的SceneKit 项目 里面会有一些示例代码，我们接下来挑一些重要的注释一下：
</p>

<p>
    <br>

</p>

<p>
</p>

<pre class="html">  SCNScene *scene = [SCNScene sceneNamed:@"art.scnassets/ship.scn"];</pre>

<p><br> <br>
从 SCN 文件中加载一个场景，也可以从.dae 文件中加载</p>

<p>
</p>

<p>
    <br>

</p>

<p>
</p>

<pre class="html">SCNNode *ship = [scene.rootNode childNodeWithName:@"ship" recursively:YES];</pre>

<p><br> <br>
获得这个场景中飞机这个节点</p>

<p>
</p>

<p>
    <img src="http://img.blog.csdn.net/20151215135133779?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt=""><br>

</p>

<p>
    <br>

</p>

<p>
    <br>

</p>

<p>
</p>

<pre class="html"> [ship runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:2 z:0 duration:1]]];</pre>

<p>
</p>

<p>
    <br>

</p>

<p>让飞机一直绕着他的Y &nbsp;轴旋转</p>

<p>
    <br>

</p>

<p>
</p>

<pre class="html"> scnView.allowsCameraControl = YES;</pre>

<p><br> <br>
让用户可以控制摄像机，配合下面一句添加手势的代码，用户可以放大，缩小 ，360 度旋转整个场景</p>

<p>
</p>

<p>
</p>

<pre class="html">gestureRecognizers addObjectsFromArray:scnView.gestureRecognizers];</pre>

<p><br> <br>
<br></p>

<pre class="html">scnView.showsStatistics = YES;      控制下方的统计栏是否显示</pre>

<p><br> <br>
<img src="http://img.blog.csdn.net/20151215135832828?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt=""><br> <br>
<br></p>

<p>
</p>

<p>
    单击手势中：
</p>

<p>
    <br>

</p>

<p>
</p>

<pre class="html">// check what nodes are tapped
    CGPoint p = [gestureRecognize locationInView:scnView];
    NSArray *hitResults = [scnView hitTest:p options:nil];</pre>

<p><br> <br>
&nbsp; &nbsp; 类似射线检测，检测二维这个点向深无限延深，这个射线上的节点，返回一个数组，可用于单击选中，数组中第一个数据一般就是我们需要的节点。</p>

<p>
</p>

<p>
    <br>

</p>

<p>
</p>

<pre class="html">     [SCNTransaction begin];
        [SCNTransaction setAnimationDuration:0.5];

        // on completion - unhighlight
        [SCNTransaction setCompletionBlock:^{
            [SCNTransaction begin];
            [SCNTransaction setAnimationDuration:0.5];

            material.emission.contents = [UIColor blackColor];

            [SCNTransaction commit];
        }];

        material.emission.contents = [UIColor redColor];

        [SCNTransaction commit];</pre>

<p><br> <br>
SceneKit 中的动画区块，类似 UIKit &nbsp;中的动画区块。<br></p>

<p>
</p>

<p>
    <br>

</p>

<p>
    OK ，起始篇 就简单到这了，下一篇跟大家分享交流 几何体如何贴图，希望大家关注。
</p>

<p>
    <br>

</p>

<p>
    我是Roc.Tian &nbsp; , 欢迎大家拍砖，交流。 邮箱：389744841@qq.com。 也欢迎上海的小伙伴周末约喝下午茶，交流，学习。
</p></div></body>
</html>